#ifndef _POINT_CLOUD_IO_H_
#define _POINT_CLOUD_IO_H_
/*
 * @Author: FamiliennameistChow nameistchow@hotmail.com
 * @Date: 2023-10-31 22:33:47
 * @LastEditors: FamiliennameistChow nameistchow@hotmail.com
 * @LastEditTime: 2023-11-07 21:30:16
 * @FilePath: /pcl_tutorials/PointCloudIO.hpp
 * @Description: 
 * loadPointCloud()
 * savePointCloud()
 * Copyright (c) 2023 by FamiliennameistChow, All Rights Reserved. 
 */

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <boost/filesystem.hpp>

typedef pcl::PointXYZI PointType;

class PointCloudIO
{
private:
    /* data */
public:
    PointCloudIO(/* args */){};
    ~PointCloudIO(){};

    static bool loadPointCloud(std::string filePath, pcl::PointCloud<PointType>::Ptr &cloud){
        boost::filesystem::path path(filePath);

        if(path.extension() == ".pcd"){
            return loadPointCloudPCD(filePath, cloud);
        }else if(path.extension() == ".ply"){
            return loadPointCloudPLY(filePath, cloud);
        }else{
            PCL_ERROR("Now only suport ply and pcd file \n");
        }
        return true;
    }

    static bool loadPointCloudPCD(std::string filePath, pcl::PointCloud<PointType>::Ptr &cloud){
        if (pcl::io::loadPCDFile<PointType>(filePath, *cloud) == -1)
        {
            PCL_ERROR("Couldn't read file \n");
            return false;
        }
        PCL_INFO("Read file %s sucessful !!! \n", filePath.c_str());
        return true;
    }

    static bool loadPointCloudPLY(std::string filePath, pcl::PointCloud<PointType>::Ptr &cloud){
        if (pcl::io::loadPLYFile<PointType>(filePath, *cloud) == -1)
        {
            PCL_ERROR("Couldn't read file \n");
            return false;
        }
        PCL_INFO("Read file %s sucessful !!! \n", filePath.c_str());
        return true;
    }

    static bool savePointCloud(std::string filePath, pcl::PointCloud<PointType>::Ptr &cloud, bool saveBinary){
        boost::filesystem::path path(filePath);
        
        if(path.extension() == ".pcd"){  // ---- pcd file save
            if(saveBinary){
                if(pcl::io::savePCDFileBinary(filePath, *cloud) == -1)
                {
                    PCL_ERROR("Couldn't write file \n");
                    return false;
                }
                PCL_INFO("Write file %s with binary mode sucessful !!! \n", filePath.c_str());
                return true;
            }else{
                if(pcl::io::savePCDFileASCII(filePath, *cloud) == -1)
                {
                    PCL_ERROR("Couldn't write file \n");
                    return false;
                }
                PCL_INFO("Write file %s sucessful !!! \n", filePath.c_str());
                return true;
            }
        }else if (path.extension() == ".ply"){ // ---- ply file save
            if(saveBinary){
                if(pcl::io::savePLYFileBinary(filePath, *cloud) == -1)
                {
                    PCL_ERROR("Couldn't write file \n");
                    return false;
                }
                PCL_INFO("Write file %s with binary mode sucessful !!! \n", filePath.c_str());
                return true;
            }else{
                if(pcl::io::savePLYFileASCII(filePath, *cloud) == -1)
                {
                    PCL_ERROR("Couldn't write file \n");
                    return false;
                }
                PCL_INFO("Write file %s sucessful !!! \n", filePath.c_str());
                return true;
            }
        }else{
            PCL_ERROR("Now only suport ply and pcd file \n");
        }
        return true;
    }
};

#endif

